package com.eascs.workflow.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.eascs.admin.o2o.backfee.entity.O2OComBackFee;
import com.eascs.admin.o2o.backfee.service.O2OComBankFeeService;
import com.eascs.admin.o2o.internal.entity.LoanapplyExpand;
import com.eascs.admin.o2o.internal.entity.LoanapplyExpandDetail;
import com.eascs.admin.o2o.internal.service.LoanapplyExpandDetailService;
import com.eascs.admin.o2o.internal.service.LoanapplyExpandService;
import com.eascs.admin.o2o.internal.util.StatusContexts;
import com.eascs.admin.o2o.loan.entity.O2oLoanUserEntity;
import com.eascs.admin.o2o.loan.entity.O2oLoanapplyEntity;
import com.eascs.admin.o2o.loan.service.O2oLoanUserService;
import com.eascs.admin.o2o.loan.service.O2oLoanapplyService;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.common.assertion.exception.AssertionException;
import com.eascs.common.assertion.util.AssertErrorUtils;
import com.eascs.loan.dao.O2oLoanDao;
import com.eascs.overdue.entity.O2oStatus;
import com.eascs.overdue.service.O2oOverdueReportService;
import com.eascs.pay.service.impl.O2oPayServiceImpl;
import com.eascs.paymentdetail.entity.O2oPaymentDetailEntity;
import com.eascs.paymentdetail.service.O2oPaymentDetailService;
import com.eascs.placeonfile.service.O2oFileService;
import com.eascs.workflow.util.TranferResult;

@Component
public class LoanapplyExpandUpdateService {
	private static Logger log = LoggerFactory.getLogger(LoanapplyExpandUpdateService.class);
	@Autowired
	private O2oLoanapplyService o2oLoanapplyService;
	@Autowired
	private O2oLoanUserService o2oLoanUserService;
	@Autowired
	private LoanapplyExpandService loanapplyExpandService;
	@Autowired
	O2OComBankFeeService o2oComBankFeeService;
	@Autowired
	O2oLoanDao loanDao;
	@Autowired
	O2oFileService fileService;
	@Autowired
	O2oPayServiceImpl o2oPayservice;
	@Autowired
	private O2oPaymentDetailService o2oPaymentDetailService;
	@Autowired
	private O2oOverdueReportService o2oOverdueReportService;
	@Autowired
	private LoanapplyExpandDetailService loanapplyExpandDetailService;

	/**
	 * 校验保证金
	 * 
	 * @param loanapplyExpand
	 * @param auditorId
	 * @param auditorName
	 * @return
	 */
	public TranferResult checkBzjStatus(LoanapplyExpand loanapplyExpand) {
		log.info("校验 billcode{}", loanapplyExpand.getBillCode());
		TranferResult tfr = new TranferResult();
		// 新系统被划拨对象
		LoanapplyExpand oldLoanapplyEx = loanapplyExpandService.fingByBillCode(loanapplyExpand.getTransferNum());
		try {
				log.info("新系统校验");
				// 判断划拨单号未完成,收取保证金与管理流程
				AssertErrorUtils.assertTrue(oldLoanapplyEx.getBillStatus().equals(StatusContexts.BZJ_STATUS_CLO), "划拨单号："+loanapplyExpand.getTransferNum()+",未收取保证金与管理费");
				// 判断划拨金额超过原单号可退保证金金额
				AssertErrorUtils.assertTrue(checkDeposit(oldLoanapplyEx.getRedDeposite(), oldLoanapplyEx.getRetaDeposite(), loanapplyExpand.getTransferDeposit()), "划拨单号："+loanapplyExpand.getTransferNum()+",划拨金额超过原单号可退保证金金额");
				// 划入对象信息
				O2oLoanapplyEntity newLoanapply = o2oLoanapplyService.findById(loanapplyExpand.getLoanapply_no());
				O2oLoanUserEntity newLoanUser = o2oLoanUserService.findById(newLoanapply.getLoanId(), newLoanapply.getLoanapplyNo());
				// 被划入对象信息
				O2oLoanapplyEntity oldLoanapply = o2oLoanapplyService.findById(oldLoanapplyEx.getLoanapply_no());
				O2oLoanUserEntity oldLoanUser = o2oLoanUserService.findById(oldLoanapply.getLoanId(), oldLoanapply.getLoanapplyNo());
				// 判断当前借款人身份证和姓名,与上笔贷款借款人姓名和身份证不匹配
				AssertErrorUtils.assertTrue(oldLoanUser.getUserFullName().equals(newLoanUser.getUserFullName()) && oldLoanUser.getDocumentNo().equals(newLoanUser.getDocumentNo()), "划拨单号："+loanapplyExpand.getTransferNum()+",当前借款人身份证和姓名,与上笔贷款借款人姓名和身份证不匹配");
				// 判断无法划拨,该单号新系统正在走退费流程
				O2OComBackFee comBackFee = o2oComBankFeeService.checkBackStatus(oldLoanapplyEx.getLoanapply_no());
				AssertErrorUtils.assertFalse(null != comBackFee && null != comBackFee.getBackDeposite() && comBackFee.getBackDeposite().compareTo(BigDecimal.ZERO) == 1, "划拨单号："+loanapplyExpand.getTransferNum()+",该单号走退费流程");
				// 校验单号是否逾期
				List<O2oStatus> o2oStatusList = o2oOverdueReportService.findBillCode(loanapplyExpand.getTransferNum());
				if (!o2oStatusList.isEmpty()) {
					List<String> strList = new ArrayList<>();
					for (int j = 0; j < o2oStatusList.size(); j++) {
						strList.add(o2oStatusList.get(j).getStatus());
					}
					AssertErrorUtils.assertFalse(!strList.contains(StatusContexts.O2O_FIVE), "划拨单号："+loanapplyExpand.getTransferNum()+",划拨贷款单的借款逾期未结清");
				}
		} catch (AssertionException e) {
			log.warn("校验异常AssertionException:" + e.getMessage(), e);
			tfr.setFlag(false);
			tfr.setResult(e.getMessage());
			return tfr;
		}

		tfr.setFlag(true);
		return tfr;
	}

	/**
	 * 校验保证金并保存
	 * 
	 * @param loanapplyExpand
	 * @param code
	 * @return
	 */
	@Transactional("o2oTransactionManager")
	public TranferResult updateBzjStatus(LoanapplyExpand loanapplyExpand, String auditorId, String auditorName,int flag) {
		TranferResult checkTranferResult = this.checkBzjStatus(loanapplyExpand);
		LoanapplyExpandDetail loanapplyExpandDetail=loanapplyExpandDetailService.queryDetail(loanapplyExpand.getId());
		if(loanapplyExpandDetail !=null && flag==1){
			LoanapplyExpand loanapplyExpand1=loanapplyExpandService.queryLoanapplyNo(loanapplyExpand.getLoanapply_no());
			loanapplyExpand1.setTransferDeposit(loanapplyExpandDetail.getTransferDeposit());
			loanapplyExpand1.setTransferNum(loanapplyExpandDetail.getTransferNum());
			loanapplyExpand1.setPaidDeposite(loanapplyExpandDetail.getPaidDeposite());
			loanapplyExpand1.setPaidManger(loanapplyExpandDetail.getPaidManger());
			loanapplyExpand1.setPaidRisk(loanapplyExpandDetail.getPaidRisk());
			BigDecimal tranDeposit=loanapplyExpandDetail.getTransferDeposit()==null?BigDecimal.ZERO:loanapplyExpandDetail.getTransferDeposit();
			loanapplyExpand1.setRedDeposite(loanapplyExpandDetail.getRedDeposite().add(loanapplyExpand1.getRedDeposite()==null?BigDecimal.ZERO:loanapplyExpand1.getRedDeposite()).add(tranDeposit));
			loanapplyExpand1.setRedManger(loanapplyExpandDetail.getRedManger().add(loanapplyExpand1.getRedManger()==null?BigDecimal.ZERO:loanapplyExpand1.getRedManger()));
			loanapplyExpand1.setRedRisk(loanapplyExpandDetail.getRedRisk().add(loanapplyExpand1.getRedRisk()==null?BigDecimal.ZERO:loanapplyExpand1.getRedRisk()));
			loanapplyExpand1.setPayRemark(loanapplyExpandDetail.getPayRemark());
			loanapplyExpand1.setSubmitDate(loanapplyExpandDetail.getSubmitDate());
			loanapplyExpand1.setPayName(loanapplyExpandDetail.getPayName());
			loanapplyExpand1.setPayDate(loanapplyExpandDetail.getPayDate());
			loanapplyExpand1.setUpdator(auditorId);
			log.info("临时表添加到loanapplyExpand主表：RedDeposite{}RedManger:{}RedRisk:{}", loanapplyExpand.getRedDeposite(),loanapplyExpand.getRedManger(),loanapplyExpand.getRedRisk());
			log.info("临时表添加到loanapplyExpand主表：RedDeposite1{}RedManger1:{}RedRisk1:{}", loanapplyExpand1.getRedDeposite(),loanapplyExpand1.getRedManger(),loanapplyExpand1.getRedRisk());
			
			loanapplyExpandService.updateById(loanapplyExpand1);
		}
		if (checkTranferResult.getFlag() == false)
			return checkTranferResult;
		log.info("校验通过开始修改BillCode：[{}],划拨单号[{}],划拨金额[{}]", loanapplyExpand.getBillCode(), loanapplyExpand.getTransferNum(), loanapplyExpand.getTransferDeposit());
		log.info("updateBzjStatus billcode :[{}]", loanapplyExpand.getBillCode());
		TranferResult tfr = new TranferResult();
		LoanapplyExpand oldLoanapplyEx = loanapplyExpandService.fingByBillCode(loanapplyExpand.getTransferNum());
		updateNewOa(loanapplyExpand, auditorId, auditorName, oldLoanapplyEx,flag);
		tfr.setFlag(true);
		return tfr;
	}

	/**
	 * 新系统修改
	 * 
	 * @param loanapplyExpand
	 * @param auditorId
	 * @param auditorName
	 * @param oldLoanapplyEx
	 */
	private void updateNewOa(LoanapplyExpand loanapplyExpand, String auditorId, String auditorName, LoanapplyExpand oldLoanapplyEx,int flag) {
		if (oldLoanapplyEx.getRetaDeposite() != null) {
			oldLoanapplyEx.setRetaDeposite(oldLoanapplyEx.getRetaDeposite().add(loanapplyExpand.getTransferDeposit()));
		} else {
			oldLoanapplyEx.setRetaDeposite(loanapplyExpand.getTransferDeposit());
		}
		loanapplyExpandService.updateById(oldLoanapplyEx);
		log.info("修改新系统保证金成功,已退保证金修改为{},新系统单号：{},编码{}", oldLoanapplyEx.getRetaDeposite(), oldLoanapplyEx.getLoanapply_no(), oldLoanapplyEx.getBillCode());
		if(flag==1){
			log.info("第一次插入收费记录详情flag：【{}】", flag);
			o2oPaymentDetailService.saveEntitys(
					addPayment(StatusContexts.BZJ_NEW_MODIFY, StatusContexts.SUBJECT_TYPE_BZJ, loanapplyExpand, auditorId, auditorName), 
					addPayment(StatusContexts.BZJ_HISTORY_NEW, StatusContexts.SUBJECT_TYPE_BZJ, loanapplyExpand, auditorId, auditorName),
					addPayment(StatusContexts.DATA_SOURCE_NEW, StatusContexts.SUBJECT_TYPE_BZJ, loanapplyExpand, auditorId, auditorName),
					addPayment(StatusContexts.DATA_SOURCE_NEW, StatusContexts.SUBJECT_TYPE_GLF, loanapplyExpand, auditorId, auditorName),
					addPayment(StatusContexts.DATA_SOURCE_NEW, StatusContexts.SUBJECT_TYPE_FXBCJ, loanapplyExpand, auditorId, auditorName));
		}else{
			log.info("多次次插入收费记录详情flag：【{}】", flag);
			o2oPaymentDetailService.saveEntitys(
					addPayment(StatusContexts.BZJ_NEW_MODIFY, StatusContexts.SUBJECT_TYPE_BZJ, loanapplyExpand, auditorId, auditorName), 
					addPayment(StatusContexts.BZJ_HISTORY_NEW, StatusContexts.SUBJECT_TYPE_BZJ, loanapplyExpand, auditorId, auditorName),
					addPayment(StatusContexts.DATA_SOURCE_NEW, StatusContexts.SUBJECT_TYPE_BZJ, loanapplyExpand, auditorId, auditorName),
					null,null);
		}
		
		log.info("/*******插入明细表成功**************/");
	}


	/**
	 * 生成明细 O2oPaymentDetailEntity对象
	 * 
	 * @param type
	 *            新老系统 old new
	 * @param code
	 *            保证金、管理费、风险补偿金
	 * @param loanapplyExpand
	 * @param userUtil
	 * @return
	 */
	public O2oPaymentDetailEntity addPayment(String type, String code, LoanapplyExpand loanapplyExpand, String auditorId, String auditorName) {
		O2oPaymentDetailEntity paymentDetil = new O2oPaymentDetailEntity();
		paymentDetil.setLoanapplyNo(loanapplyExpand.getLoanapply_no());
		if (StatusContexts.DATA_SOURCE_NEW.equals(type)) {
			paymentDetil.setBillCode(loanapplyExpand.getBillCode());
			paymentDetil.setHappenSource(loanapplyExpand.getBillCode());
			paymentDetil.setPaymentType(StatusContexts.PAYMENT_TYPE_S);
			if (StatusContexts.SUBJECT_TYPE_BZJ.equals(code)) {
				paymentDetil.setSubjectType(StatusContexts.SUBJECT_TYPE_BZJ);
				if (null == loanapplyExpand.getReceiveDeposit()) {
					paymentDetil.setAmountMoney(loanapplyExpand.getRedDeposite());
					paymentDetil.setRemark("系统单号:" + loanapplyExpand.getBillCode() + ",收取保证金：" + loanapplyExpand.getRedDeposite());
				} else {
					paymentDetil.setAmountMoney(loanapplyExpand.getReceiveDeposit());
					paymentDetil.setRemark("系统单号:" + loanapplyExpand.getBillCode() + ",收取保证金：" + loanapplyExpand.getReceiveDeposit());
				}
			} else if (StatusContexts.SUBJECT_TYPE_GLF.equals(code)) {
				paymentDetil.setSubjectType(StatusContexts.SUBJECT_TYPE_GLF);
				paymentDetil.setAmountMoney(loanapplyExpand.getRedManger());
				paymentDetil.setRemark("系统单号:" + loanapplyExpand.getBillCode() + "收取管理费：" + loanapplyExpand.getRedManger());
			} else {
				paymentDetil.setSubjectType(StatusContexts.SUBJECT_TYPE_FXBCJ);
				paymentDetil.setAmountMoney(loanapplyExpand.getRedRisk());
				paymentDetil.setRemark("系统单号:" + loanapplyExpand.getBillCode() + ",收取风险补偿金：" + loanapplyExpand.getRedRisk());
			}
		} else if (StatusContexts.DATA_SOURCE_OLD.equals(type)) {
			log.info("旧系统划出单号：{}，划出金额：{}", loanapplyExpand.getTransferNum(), loanapplyExpand.getTransferDeposit());
			paymentDetil.setBillCode(loanapplyExpand.getTransferNum());
			paymentDetil.setSubjectType(StatusContexts.SUBJECT_TYPE_BZJ);
			paymentDetil.setHappenSource(loanapplyExpand.getBillCode());
			paymentDetil.setRemark("系统单号:" + loanapplyExpand.getTransferNum() + ",划出保证金：" + loanapplyExpand.getTransferDeposit() + ",划入单号：" + loanapplyExpand.getBillCode());
			paymentDetil.setPaymentType(StatusContexts.PAYMENT_TYPE_XF);
			paymentDetil.setAmountMoney(loanapplyExpand.getTransferDeposit());
		} else if (StatusContexts.BZJ_NEW_MODIFY.equals(type)) {
			paymentDetil.setBillCode(loanapplyExpand.getTransferNum());
			paymentDetil.setSubjectType(StatusContexts.SUBJECT_TYPE_BZJ);
			paymentDetil.setHappenSource(loanapplyExpand.getBillCode());
			paymentDetil.setRemark("系统单号:" + loanapplyExpand.getTransferNum() + ",划出保证金：" + loanapplyExpand.getTransferDeposit() + ",划入单号：" + loanapplyExpand.getBillCode());
			paymentDetil.setPaymentType(StatusContexts.PAYMENT_TYPE_XF);
			paymentDetil.setAmountMoney(loanapplyExpand.getTransferDeposit());
		} else {
			paymentDetil.setBillCode(loanapplyExpand.getBillCode());
			paymentDetil.setSubjectType(StatusContexts.SUBJECT_TYPE_BZJ);
			paymentDetil.setHappenSource(loanapplyExpand.getBillCode());
			paymentDetil.setRemark("系统单号:" + loanapplyExpand.getBillCode() + ",划入保证金：" + loanapplyExpand.getTransferDeposit() + ",划出单号：" + loanapplyExpand.getTransferNum());
			paymentDetil.setPaymentType(StatusContexts.PAYMENT_TYPE_XS);
			paymentDetil.setAmountMoney(loanapplyExpand.getTransferDeposit());
		}
		paymentDetil.setOperationName(auditorName);
		paymentDetil.setOperationNo(auditorId);
		paymentDetil.setUpdateTime(loanapplyExpand.getPayDate());
		paymentDetil.setRecordTime(new Date());
		return paymentDetil;
	}

	/**
	 * 校验新老系统保证金
	 * 
	 * @param recDeposit
	 * @param retnDeposit
	 * @return
	 */
	public boolean checkDeposit(BigDecimal recDeposit, BigDecimal retnDeposit, BigDecimal transferDeposit) {
		boolean flag = true;
		BigDecimal amount = recDeposit.subtract(null == retnDeposit ? BigDecimal.ZERO : retnDeposit);
		if (amount.compareTo(transferDeposit) == -1) {
			flag = false;
		}
		return flag;
	}

}
